package src.percolation;

import java.io.IOException;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;

import src.exceptions.NonPercolatingClusterException;
import src.utils.Utils;
import src.utils.XYPosition;

public class Pr5 {
	private static final double pc = 0.596;

	public static void main(String[] argvs) throws IOException {	
		
		int large; 
		
		double multiplier;
		double tolerance;
		double eps;
		
		String outputName;
		
		try {
			large = new Integer(argvs[0]);
			tolerance = new Double(argvs[1]);
			multiplier = new Double(argvs[2]);
			eps = new Double(argvs[3]);
			outputName =  argvs[4];
			
		} catch (Exception e) {
			showUsage();
			return;
		}
		
		Map<Integer,Double> densities = new TreeMap<Integer, Double>();
		
		Red myRed = generateValidGrid(large, tolerance, new Random(),eps);
				
		for(int windowSize = large/100; windowSize<large; windowSize *= multiplier) {
			
			double density = myRed.densityInWindow(windowSize);
			
			densities.put(windowSize, density);
		}
		
		Utils.printToFile(densities, outputName+"-"+Math.floor((pc+eps)*10000));
	}

	private static void showUsage() {
		System.out.println("Usage: ");
		
		System.out.println("<large> <tolerance> <multiplier> <outputName>\n");
		
		System.out.println("<large>: size of net.");
		System.out.println("<tolerance>: How de-centered can the grid be. Write as 5% is 0.05.");
		System.out.println("<multiplier>: To increment on the iteration.");
		System.out.println("<eps>: How much above pc will the grid be populated.");
		System.out.println("<outputName>: Where to write the results: OutputName+probability");			
	}

	/*
	 * large: of the grid to generate
	 * tolerance: relative of of the mass center of the percolating
	 * cluster, from the center of the grid. e.g: 0.05 is 5%
	 * gen: random numbers generator
	 */
	public static Red generateValidGrid(int large,double tolerance,Random gen,double eps){
		
		Red red = null;
		XYPosition massCenter;
		double xDev;
		double yDev;
		
		//generate a valid grid. must percolate, and be somehow "centered"
		do{
			try{
				long seed = gen.nextLong();
				red = new Red(large,seed);
				red.createGrid(pc+eps); //proba ~ pc +eps.
				
				massCenter = red.massCenterOfPercolatingCluter();
				xDev = Math.abs(massCenter.getX()-large/2)/(large*1.0);
				yDev = Math.abs(massCenter.getY()-large/2)/(large*1.0);
				
			}catch(NonPercolatingClusterException e) {
				//stupid condition, to re populate grid
				xDev = tolerance;
				yDev = tolerance;
			}
		} while(xDev >= tolerance || yDev >= tolerance);
			
		//now, we have a good grid
		return red;
	}
}
